import pygame
import sys
from pygame.locals import *
from random import randint

# pygame初始化
pygame.init()
pygame.mixer.init()  # 为音频做准备

# 设置游戏窗口大小
size = width, height = 1600, 900
screen = pygame.display.set_mode(size)
pygame.display.set_caption('逃离莫塔里的土豆雷')  # 标题
clock = pygame.time.Clock()  # 创建时钟对象用于控制帧率


# 图片缩放函数
def scale_image(image, target_width, target_height):
    """按目标尺寸缩放图片，确保完全贴合窗口"""
    return pygame.transform.scale(image, (target_width, target_height))


# 游戏主界面
def game_menu():
    """显示游戏主界面，包含开始和退出按钮"""
    # 加载背景
    try:
        menu_bg = pygame.image.load('开始背景图.jpg')
        menu_bg = scale_image(menu_bg, width, height)  # 缩放至窗口大小
    except:
        print("无法加载游戏主界面图片")
        menu_bg = pygame.Surface((width, height))
        menu_bg.fill((0, 0, 100))  # 蓝色背景作为替代

    # 加载按钮
    try:
        start_button = pygame.image.load('开始按钮.jpg')
        # 按原始尺寸的10%缩放
        start_button = scale_image(start_button,
                                   int(start_button.get_width() * 0.1),
                                   int(start_button.get_height() * 0.1))
        exit_button = pygame.image.load('退出按钮.jpg')
        exit_button = scale_image(exit_button,
                                  int(exit_button.get_width() * 0.1),
                                  int(exit_button.get_height() * 0.1))
    except:
        print("无法加载按钮图片")
        start_button = pygame.Surface((300, 100))
        start_button.fill((0, 255, 0))  # 绿色按钮
        exit_button = pygame.Surface((300, 100))
        exit_button.fill((255, 0, 0))  # 红色按钮

    # 设置按钮位置
    start_rect = start_button.get_rect(center=(width // 2, height // 2 - 100))
    exit_rect = exit_button.get_rect(center=(width // 2, height // 2 + 100))

    # 主界面循环
    while True:
        screen.blit(menu_bg, (0, 0))
        screen.blit(start_button, start_rect)
        screen.blit(exit_button, exit_rect)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # 左键点击
                    if start_rect.collidepoint(event.pos):
                        return character_selection()  # 进入角色选择界面
                    elif exit_rect.collidepoint(event.pos):
                        pygame.quit()
                        sys.exit()

        pygame.display.flip()
        clock.tick(60)


# 角色选择界面
def character_selection():
    """角色选择界面，显示六个角色供玩家选择"""
    # 加载背景
    try:
        select_bg = pygame.image.load('背景.jpg')
        select_bg = scale_image(select_bg, width, height)  # 缩放至窗口大小
    except:
        print("无法加载角色选择背景图")
        select_bg = pygame.Surface((width, height))
        select_bg.fill((200, 200, 200))  # 灰色背景作为替代

    # 加载角色图片
    characters = []
    character_rects = []
    for i in range(1, 7):  # 加载6个角色
        try:
            character_img = pygame.image.load(f'角色{i}.jpg')
            # 按原始尺寸的10%缩放
            character_img = scale_image(character_img,
                                        int(character_img.get_width() * 0.1),
                                        int(character_img.get_height() * 0.1))
            characters.append(character_img)
        except:
            print(f"无法加载角色{i}图片")
            # 创建临时角色图片
            temp_img = pygame.Surface((100, 150))
            temp_img.fill((i * 30 % 255, i * 50 % 255, i * 70 % 255))
            characters.append(temp_img)

    # 计算角色排列位置（三行三列）
    spacing_x = width // 8
    spacing_y = height // 5
    start_x = spacing_x * 2
    start_y = spacing_y * 2

    for i, char in enumerate(characters):
        x = start_x + (i % 3) * (width - start_x * 2) // 2
        y = start_y + (i // 3) * spacing_y
        rect = char.get_rect(center=(x, y))
        character_rects.append(rect)

    # 角色选择界面循环
    while True:
        screen.blit(select_bg, (0, 0))

        # 绘制角色和选择提示
        font = pygame.font.Font(None, 50)
        title = font.render("请选择游戏角色", True, (255, 255, 255))
        screen.blit(title, (width // 2 - title.get_width() // 2, spacing_y))

        for i, char in enumerate(characters):
            screen.blit(char, character_rects[i])

        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # 左键点击
                    for i, rect in enumerate(character_rects):
                        if rect.collidepoint(event.pos):
                            return i + 1  # 返回选择的角色编号

        pygame.display.flip()
        clock.tick(60)


# 游戏成功结束界面
def game_success():
    """显示游戏成功结束界面，包含退出按钮"""
    # 加载背景
    try:
        success_bg = pygame.image.load('莫塔里小丑.jpg')
        success_bg = scale_image(success_bg, width, height)  # 缩放至窗口大小
    except:
        print("无法加载游戏成功图片")
        success_bg = pygame.Surface((width, height))
        success_bg.fill((0, 100, 0))  # 绿色背景作为替代

    # 加载按钮
    try:
        exit_button = pygame.image.load('退出按钮.jpg')
        # 按原始尺寸的10%缩放
        exit_button = scale_image(exit_button,
                                  int(exit_button.get_width() * 0.1),
                                  int(exit_button.get_height() * 0.1))
    except:
        print("无法加载退出按钮图片")
        exit_button = pygame.Surface((300, 100))
        exit_button.fill((255, 0, 0))  # 红色按钮

    # 设置按钮位置
    exit_rect = exit_button.get_rect(center=(width // 2, height // 2 + 150))

    # 成功界面循环
    while True:
        screen.blit(success_bg, (0, 0))
        screen.blit(exit_button, exit_rect)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1 and exit_rect.collidepoint(event.pos):
                    pygame.quit()
                    sys.exit()

        pygame.display.flip()
        clock.tick(60)


# 主函数
def main():
    # 显示游戏主界面并获取选择的角色
    selected_character = game_menu()

    # 游戏背景音乐
    try:
        pygame.mixer.music.load('背景音乐.mp3')
        pygame.mixer.music.set_volume(0.2)
        pygame.mixer.music.play(loops=-1)
    except:
        print("无法加载背景音乐")

    # 加载并缩放开始背景图
    try:
        bg = pygame.image.load('背景.jpg')
        bg = scale_image(bg, width, height)  # 缩放至窗口大小
    except:
        print("无法加载开始背景图")
        bg = pygame.Surface((width, height))
        bg.fill((255, 255, 255))
    bg_position = bg.get_rect()

    class Up(pygame.sprite.Sprite):  # 定义要选择的游戏人物
        def __init__(self, character_id):
            super().__init__()  # 正确调用父类初始化方法
            position = 100, 100  # 设置初始位置

            # 加载选择的角色图片
            try:
                character_img = pygame.image.load(f'角色{character_id}.jpg')
                # 缩放人物图片为原始大小的5%
                self.image = scale_image(character_img,
                                         int(character_img.get_width() * 0.05),
                                         int(character_img.get_height() * 0.05))
            except:
                print(f"无法加载角色{character_id}图片")
                # 创建一个临时人物
                self.image = pygame.Surface((50, 50))
                self.image.fill((character_id * 30 % 255, character_id * 50 % 255, character_id * 70 % 255))
            self.rect = self.image.get_rect()  # 获取游戏人物的矩形区域
            self.rect.center = position  # 把区域设置为默认位置

        # 人物的移动方法
        def move_left(self):
            self.speed = [-5, 0]
            if self.rect.left <= 0:
                self.rect.left = 0
            else:
                self.rect = self.rect.move(self.speed)

        def move_right(self):
            self.speed = [5, 0]
            if self.rect.right >= width:
                self.rect.right = width
            else:
                self.rect = self.rect.move(self.speed)

        def move_up(self):
            self.speed = [0, -5]
            if self.rect.top <= 0:
                self.rect.top = 0
            else:
                self.rect = self.rect.move(self.speed)

        def move_down(self):
            self.speed = [0, 5]
            if self.rect.bottom >= height:
                self.rect.bottom = height
            else:
                self.rect = self.rect.move(self.speed)

    # 定义土豆雷
    class KLT(pygame.sprite.Sprite):
        def __init__(self):
            super().__init__()
            y = randint(0, height - 100)
            position = [width, y]

            try:
                original_image = pygame.image.load('土豆雷.jpg')
                # 缩放土豆雷图片为原始大小的5%
                self.image = scale_image(original_image,
                                         int(original_image.get_width() * 0.05),
                                         int(original_image.get_height() * 0.05))
            except:
                print("无法加载土豆雷图片")
                self.image = pygame.Surface((50, 50))
                self.image.fill((255, 0, 0))
            self.rect = self.image.get_rect()
            self.rect.center = position
            self.speed = [-3, 0]

        def move(self):
            self.rect = self.rect.move(self.speed)

    # 对主循环进行初始化
    up = Up(selected_character)
    i = 0
    klt_group = pygame.sprite.Group()
    state = True

    # 设置主循环
    while state:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        # 设置键盘控制
        key = pygame.key.get_pressed()
        if key[K_LEFT]:
            up.move_left()
        if key[K_RIGHT]:
            up.move_right()
        if key[K_UP]:
            up.move_up()
        if key[K_DOWN]:
            up.move_down()

        # 游戏成功判定：人物到达窗口右侧
        if up.rect.right >= width:
            game_success()
            state = False

        # 设置游戏画面更新
        screen.blit(bg, bg_position)
        screen.blit(up.image, up.rect)

        # 让土豆雷在屏幕右侧随机大量出现
        i = i + 1
        if i % 10 == 0:
            klt = KLT()
            klt_group.add(klt)

        # 判断功能，当人物碰到土豆雷时游戏结束
        for k in klt_group.sprites():
            k.move()
            if k.rect.right < 0:
                klt_group.remove(k)
                continue
            screen.blit(k.image, k.rect)
            if pygame.sprite.collide_rect(up, k):
                state = False
                pause()  # 调用结束函数

        pygame.display.flip()
        clock.tick(60)


# 设置游戏结束函数 pause
def pause():
    global screen, width, height
    try:
        original_bg_go = pygame.image.load('莫塔里的大手.jpg')
        bg_go = scale_image(original_bg_go, width, height)  # 缩放至窗口大小
    except:
        print("无法加载游戏结束图片")
        bg_go = pygame.Surface((width, height))
        bg_go.fill((0, 0, 0))
    bg_go_pos = bg_go.get_rect()

    pygame.display.set_caption('GameOver')

    try:
        original_button = pygame.image.load('重来按钮.jpg')
        # 缩放按钮图片为原始大小的10%
        img_src = scale_image(original_button,
                              int(original_button.get_width() * 0.1),
                              int(original_button.get_height() * 0.1))
    except:
        print("无法加载重玩按钮图片")
        img_src = pygame.Surface((200, 100))
        img_src.fill((255, 255, 0))

    img_src_pos = img_src.get_rect()
    img_src_pos.center = (width // 2, height // 2 + 100)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    if img_src_pos.collidepoint(event.pos):
                        main()  # 重新开始游戏

        screen.blit(bg_go, bg_go_pos)
        screen.blit(img_src, img_src_pos)

        pygame.display.flip()
        clock.tick(60)


if __name__ == "__main__":
    main()